/**
 * 
 */
package com.suyx.job.controller;

import java.awt.Point;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Optional;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.suyx.job.config.BaiduOCR;
import com.suyx.job.config.RedisUtils;
import com.suyx.job.core.IHoldService;
import com.suyx.job.entity.Result;
import com.suyx.job.entity.RoleInfo;
import com.suyx.job.entity.TuInfo;
import com.suyx.job.service.IRoleInfoService;
import com.suyx.job.service.ITuInfoService;
import com.suyx.job.service.area.IGoAreaService;
import com.suyx.job.service.sect.IGoToSectService;
import com.suyx.job.utils.ImagePHash;
import com.suyx.job.utils.ImageUtils;
import com.suyx.job.utils.ScreenCapture;
import com.suyx.job.utils.SpeechUtil;
import com.suyx.job.utils.SysStaticData;
import com.suyx.job.utils.SysStaticWqData;

import lombok.extern.slf4j.Slf4j;

/**
 * @author Administrator
 *
 */
@Slf4j
@RestController
@RequestMapping("/mhxyWt")
public class MhxyWTController {

	
	private static final List<String> bgzb1 = Arrays.asList("730 224", "809 212", "906 233", "1000 224", "1084 224",
											          "730 321", "811 324", "909 315", "1000 320", "1080 324",
											          "724 408", "812 408", "909 408", "1000 408", "1080 408",
											          "718 492", "812 492", "909 492", "1000 492", "1080 492");

    private static final List<String> bgzb = Arrays.asList("909 315", "1000 320", "1080 324",
											         "724 408", "812 408", "909 408", "1000 408", "1080 408",
											         "718 492", "812 492", "909 492", "1000 492", "1080 492");

	
    private static final List<String> ck_bgzb = Arrays.asList("270 250", "360 250", "450 250", "540 250", "630 250",
	          "270 340", "360 340", "450 340", "540 340", "630 340",
	          "270 430", "360 430", "450 430", "540 430", "630 430",
	          "270 520", "360 520", "450 520", "540 520", "630 520");

    @Autowired
    private BaiduOCR baiduOCR;

    @Autowired
	private IRoleInfoService roleService;
    @Autowired
    private ITuInfoService tuInfoService;
    @Autowired
	protected IHoldService holdService;
    @Autowired
	private RedisUtils redisService;
    
    public <T> T getService(Class<T> t) throws Exception {
		return holdService.getServiceInstance(t);
	}

	public <T> T getService(String serviceName, Class<T> clazz) throws Exception {
		return holdService.getServiceInstance(serviceName);
	}
	@PostMapping("/getTuInfo")
    public Result getTuInfo(Integer roleId) throws Exception{
    	//String text_areaWaTu = "东海湾&长寿郊外&大唐国境&大唐境外&江南野外&傲来国&墨家村&普陀山&狮驼岭&五庄观&朱紫国&麒麟山&花果山&建邺城&女儿村&北俱芦洲";
    	RoleInfo roleInfo = roleService.getOne(roleId);
    	String device = roleInfo.getDevice();
    	String path = SysStaticData.SC_PIC_PATH + device + "\\";
    	tuInfoService.deleteByRoleIdAndStatus(roleId, "0");
    	//打开仓库
    	openCk(roleInfo,path);
		
		boolean flag = false;
		for(String key:SysStaticData.CK_ZB.keySet()){
			if(flag){
				break;
			}
			
			ScreenCapture.mouseClick(device, "345 619");
    		ScreenCapture.mouseClick(device, key.split("&")[0]+" "+key.split("&")[1]);
    		for(String key1:SysStaticData.CK_ZB_N.keySet()){
    			ScreenCapture.mouseClick(device, key1.split("&")[0]+" "+key1.split("&")[1]);
        		try {
					Thread.sleep(5 * 100L);
					String text = readBaotuInfo(roleInfo,key,key1);
					if(StringUtils.isEmpty(text)){
						flag = true;
						SpeechUtil.textToSpeech(roleInfo.getRoleName() + "读取藏宝图数据完成");
						log.info(roleInfo.getRoleName() + "读取藏宝图数据完成");
						break;
					}
				} catch (Exception e) {
				}
    		}
    		
		}
    	
		return new Result(true,"["+roleInfo.getRoleName()+"]宝图数据读取完成!");
    }

	@PostMapping(value="/wt")
    @SuppressWarnings("unchecked")
    public Result wt(Integer roleId) throws Exception{
		RoleInfo roleInfo = roleService.getOne(roleId);
		while(true){
			Integer sectNum = (Integer) Optional.ofNullable(redisService.get(roleInfo.getRoleName())).orElse(0);
			if(sectNum >= 20){
				SpeechUtil.textToSpeech(roleInfo.getRoleName() + "今天已经设置不能挖图任务");
				log.info(roleInfo.getRoleName() + "今天已经设置不能挖图任务");
				break;
			}
			
			if(singleWt(roleInfo)){
				break;
			}
		}
		return new Result(true,"["+roleInfo.getRoleName()+"]挖图结束!");
		
	}
	

	@SuppressWarnings("unchecked")
    private boolean singleWt(RoleInfo roleInfo) throws Exception{
    	String device = roleInfo.getDevice();
    	String path = SysStaticData.SC_PIC_PATH + device + "\\";
    	TuInfo tuInfo = new TuInfo();
    	tuInfo.setStatus("1");
    	tuInfo.setRoleId(roleInfo.getRoleId());
		List<TuInfo> da_baoTus = (List<TuInfo>) tuInfoService.findTuPage(tuInfo, 0, 11).getData();
		if(da_baoTus.size() == 0){
			//==========================================仓库取图============================
	    	//打开仓库
	    	openCk(roleInfo,path);
	    	
	    	tuInfo.setDevice(device);
	    	tuInfo.setStatus("0");
	    	tuInfo.setRoleId(roleInfo.getRoleId());
			List<TuInfo> baoTus = (List<TuInfo>) tuInfoService.findTuPage(tuInfo, 0, 11).getData();
	    	String ckNo = "";
	    	Integer i = 7;
			for(TuInfo tu:baoTus){
				TuInfo baotu = tu;
				if(!ckNo.equals(tu.getCkNo())){
					ScreenCapture.mouseClick(device, "345 619");
					//Thread.sleep(1 * 1000L);
					ScreenCapture.mouseClick(device, tu.getCkLocation()
							.split("&")[0]+" "+tu.getCkLocation().split("&")[1]);
				}
				if(i > 17){
					log.info("仓库取图完成！");
		        	break;
				}
				//Thread.sleep(1 * 500L);
				ScreenCapture.mouseClick(device, tu.getCkLocation()
						.split("&")[2]+" "+tu.getCkLocation().split("&")[3]);
				
				ckNo = tu.getCkNo();
				//Thread.sleep(1 * 500L);
				ScreenCapture.mouseClick(device, "698 423");
				
				baotu.setBgLocation(SysStaticData.BG_ZB_BT_F.get(String.valueOf(i)));
	        	baotu.setStatus("1");
	        	tuInfoService.saveAndFlush(baotu);
	        	i++;
	        	
				// 判断是否存入包裹
				/*ScreenCapture.mouseClick(device, tu.getCkLocation()
						.split("&")[2]+" "+tu.getCkLocation().split("&")[3]);
				
				ScreenCapture.snapshot(device,path, "screen.png");
		        ImageUtils.cutPNG(new FileInputStream(path +"screen.png"),
		                new FileOutputStream(path + device +".png"), 710,222,70,63);
				ImagePHash p = new ImagePHash();
		        String image1 = p.getHash(new FileInputStream(new File(path + device + ".png")));
		        String image2 = p.getHash(new FileInputStream(new File(SysStaticData.SC_PIC_PATH +"is_baotu.png")));
		        int score =  p.distance(image1, image2);*/
	    	}
			//==========================================仓库取图============================
			//关闭仓库
			ScreenCapture.mouseClick(device, "1139 47");
			tuInfo.setStatus("1");
			tuInfo.setRoleId(roleInfo.getRoleId());
			da_baoTus = (List<TuInfo>) tuInfoService.findTuPage(tuInfo, 0, 11).getData();
		}
    	
		//==========================================开始挖图================================
		
		String scene = "";
		for(TuInfo tu:da_baoTus){
			// 点香
			dianXiang(roleInfo,path);
			
			TuInfo baotu = tu;
			if(!scene.equals(tu.getScene())){
				//去任务地方
				holdService.getServiceInstances(IGoAreaService.class).stream()
					.filter(s -> s.support(tu.getSceneCode()))
					.forEach(s -> s.execute(roleInfo.getDevice(), path, tu.getSceneCode()));
			}
			
			//回师门
			if(SysStaticData.AERA.get(tu.getScene()).equals(roleInfo.getRoleSect())){
				holdService.getServiceInstances(
						IGoToSectService.class).stream().filter(s -> s.support(roleInfo))
						.forEach(s -> s.goBackHome(roleInfo, path));
			}
			
			scene = tu.getScene();
	        log.info(roleInfo.getRoleName() + "挖图任务: 到达" + tu.getScene());
	        
	        //去坐标点挖图
	        holdService.getServiceInstances(IGoAreaService.class).stream()
						.filter(s -> s.support(tu.getSceneCode()))
						.forEach(s -> s.goToPoint(roleInfo,path,tu));
	        
	        baotu.setStatus("2");
	        baotu.setFinishTime(new Date());
        	tuInfoService.saveAndFlush(baotu);
	        
		}
		
		//==========================================挖图物品存入仓库============================
		if(da_baoTus.size() > 0){
			openCk(roleInfo,path);
			saveWp(roleInfo,path);
			//关闭仓库
			//ScreenCapture.mouseClick(device, "1139 47");
		}else{
			SpeechUtil.textToSpeech(roleInfo.getRoleName() + "已经没有可以挖取得藏宝图");
			log.info(roleInfo.getRoleName() + "已经没有可以挖取得藏宝图");
			return true;
		}
		
		
		return false;
    }
    
    private void openCk(RoleInfo roleInfo,String path)throws Exception{
    	String device = roleInfo.getDevice();
    	ScreenCapture.snapshot(device,path, "screen.png");
        ImageUtils.cutPNG(new FileInputStream(path +"screen.png"),
                new FileOutputStream(path + device +".png"), 527,603,143,43);
		ImagePHash p = new ImagePHash();
        String image1 = p.getHash(new FileInputStream(new File(path + device + ".png")));
        String image2 = p.getHash(new FileInputStream(new File(SysStaticData.SC_PIC_PATH +"is_ck.png")));
        int score =  p.distance(image1, image2);
        
        if(score != 0){
        	ScreenCapture.mouseClick(device, "1308 675");// # 打开包裹
    		Thread.sleep(500L);
    		ScreenCapture.mouseClick(device, "715 305");// 打开ca2 2-1
    		Thread.sleep(500L);
    		ScreenCapture.mouseClick(device, "522 422");// 使用
    		ScreenCapture.mouseClick(device, "488 421");// 长安群雄仓库
    		ScreenCapture.mouseClick(device, "1156 52");// 关闭包裹
    		// 点击仓库NPC
    		Thread.sleep(1 * 1000L);
    		ScreenCapture.mouseClick(device, "664 292");
    		Thread.sleep(1 * 1000L);
    		ScreenCapture.mouseClick(device, "1228 442");
        }
        Thread.sleep(500L);
    	ScreenCapture.mouseClick(device, "774 137");// # 点击道具栏
    }
    
    // 获取宝图坐标信息
 	private String  readBaotuInfo(RoleInfo roleInfo,String ckNO,String ckZuoBiao) throws Exception {
 		String device = roleInfo.getDevice();
		String roleSect = roleInfo.getRoleSect();
		String path = SysStaticData.SC_PIC_PATH + device + "\\";
		
 		ScreenCapture.snapshot(device, path, "screen.png");
 		Thread.sleep(5 * 100L);
 		ImageUtils.cutPNG(new FileInputStream(path + "screen.png"), new FileOutputStream(path + device + ".png"), 792,
 				359, 217, 38);// y52
 		String text = baiduOCR.generalBasic(path + device + ".png");// 33 535
 		
 		for (String key : SysStaticData.AERA.keySet()) {
    		if (text.indexOf(key) > -1) {
				if ("大唐".equals(key) && text.indexOf("大唐国境") > -1) {
					continue;
				}
				if ("大唐".equals(key) && text.indexOf("大唐境外") > -1) {
					continue;
				}
				if ("花果".equals(key) && text.indexOf("花果山") > -1) {
					continue;
				}
				if ("麒麟山".equals(key) && "50".equals(roleInfo.getRemark3())) {
					continue;
				}
				String[] arrayTuInfo = text.split("\\(");
				if(arrayTuInfo.length > 1){
					String[] tuInfo = arrayTuInfo[1].replace(")", "").split(",");
					if(tuInfo.length > 1){
						TuInfo info = new TuInfo();
						info.setScene(key);
						info.setSceneCode(SysStaticData.AERA.get(key));
						info.setCkLocation(ckNO+"&"+ckZuoBiao);
						info.setCkNo(SysStaticData.CK_ZB.get(ckNO));
						info.setOrderNo(SysStaticData.CK_ZB_N.get(ckZuoBiao));
						info.setDevice(device);
						info.setRoleId(roleInfo.getRoleId());
						info.setStatus("0");
						info.setZuobiaoX(Integer.valueOf(tuInfo[0]));
						info.setZuobiaoY(Integer.valueOf(tuInfo[1]));
						
						String[] orPoint = SysStaticData.POINT_DISTANCE.get(SysStaticData.AERA.get(key)).split("&");
						Point p1 = new Point(Integer.valueOf(orPoint[0]),Integer.valueOf(orPoint[1]));
						Point p2 = new Point(Integer.valueOf(tuInfo[0]),Integer.valueOf(tuInfo[1]));
						// 计算两点间距离公式 
					    double juli = Math.sqrt(Math.abs((p1.getX() - p2.getX())* (p1.getX() - p2.getX())+(p1.getY() - p2.getY())* (p1.getY() - p2.getY()))); 
					    info.setDistance(juli);
					    tuInfoService.saveAndFlush(info);
					}else{
						text = baiduOCR.accurateBasic(path + device + ".png");// 33 535
						arrayTuInfo = text.split("\\(");
						if(arrayTuInfo.length > 1){
							tuInfo = arrayTuInfo[1].replace(")", "").replace(".", ",").split(",");
							if(tuInfo.length > 1){
								TuInfo info = new TuInfo();
								info.setScene(key);
								info.setSceneCode(SysStaticData.AERA.get(key));
								info.setCkLocation(ckNO+"&"+ckZuoBiao);
								info.setCkNo(SysStaticData.CK_ZB.get(ckNO));
								info.setOrderNo(SysStaticData.CK_ZB_N.get(ckZuoBiao));
								info.setDevice(device);
								info.setRoleId(roleInfo.getRoleId());
								info.setStatus("0");
								info.setZuobiaoX(Integer.valueOf(tuInfo[0]));
								info.setZuobiaoY(Integer.valueOf(tuInfo[1]));
								
								String[] orPoint = SysStaticData.POINT_DISTANCE.get(SysStaticData.AERA.get(key)).split("&");
								Point p1 = new Point(Integer.valueOf(orPoint[0]),Integer.valueOf(orPoint[1]));
								Point p2 = new Point(Integer.valueOf(tuInfo[0]),Integer.valueOf(tuInfo[1]));
								// 计算两点间距离公式 
							    double juli = Math.sqrt(Math.abs((p1.getX() - p2.getX())* (p1.getX() - p2.getX())+(p1.getY() - p2.getY())* (p1.getY() - p2.getY()))); 
							    info.setDistance(juli);
							    
								tuInfoService.saveAndFlush(info);
							}
						}
					}
				}
				break;
    		}
    	}
 		return text;
 	}
 	
 	@SuppressWarnings("unchecked")
	private String  saveWp(RoleInfo roleInfo,String path) throws Exception {
    	String device = roleInfo.getDevice();
    	TuInfo tuInfo = new TuInfo();
    	tuInfo.setStatus("2");
    	tuInfo.setRoleId(roleInfo.getRoleId());
		List<TuInfo> da_baoTus = (List<TuInfo>) tuInfoService.findTuPage(tuInfo, 0, 11).getData();
    	String ckNo = "";
		for(TuInfo wp :da_baoTus){
    		TuInfo baotu = wp;
    		if(!ckNo.equals(wp.getCkNo())){
    			ScreenCapture.mouseClick(device, "345 619");
    			ScreenCapture.mouseClick(device, wp.getCkLocation().split("&")[0]+ " "+wp.getCkLocation().split("&")[1]);
    		}
    		
    		ScreenCapture.mouseClick(device, wp.getBgLocation().replace("&", " "));
    		
    		ScreenCapture.snapshot(device, path, "screen.png");
			Thread.sleep(5 * 100L);
			ImageUtils.cutPNG(new FileInputStream(path + "screen.png"), new FileOutputStream(path + device + ".png"), 428,
					222, 123, 42);// y52 244 307
			String text = baiduOCR.generalBasic(path + device + ".png");// 33 535
			log.info(text);
			if(text.indexOf("召唤兽") > -1){
				ImageUtils.cutPNG(new FileInputStream(path + "screen.png"), new FileOutputStream(path + device + ".png"), 504,
    					389, 73, 25);// y52 244 307
    		    text = baiduOCR.generalBasic(path + device + ".png");// 33 535
    			log.info(text);
			}
			
			String wp_save_zb = SysStaticWqData.WQ_TYPE.get(text);
			//物品放入仓库
			if(StringUtils.isNoneBlank(wp_save_zb)){
				ScreenCapture.mouseClick(device, wp_save_zb.replaceAll("&", " "));
			}
			baotu.setStatus("3");
			baotu.setRemark(text);
        	tuInfoService.saveAndFlush(baotu);
        	
        	ckNo = wp.getCkNo();
    	}
 		return "";
 	}
 	
 	private void dianXiang(RoleInfo roleInfo,String path){
 		String device = roleInfo.getDevice();
 		String xiang_time = (String) redisService.get("xiang_time"+roleInfo.getRoleId());
	    if (StringUtils.isEmpty(xiang_time)) {
			//使用摄药香
			ScreenCapture.mouseClick(device, "1308 675");// # 打开包裹
			ScreenCapture.mouseClick(device, "987 488");// # 
			ScreenCapture.mouseClick(device, "511 404");// # 
			ScreenCapture.mouseClick(device, "1156 52");// 关闭包裹
			redisService.set("xiang_time"+roleInfo.getRoleId(), "xiang_time",1680l);
		}
 	}
 	
 	private void dianXiang1(RoleInfo roleInfo,String path){
 		String device = roleInfo.getDevice();
 		String xiang_time = (String) redisService.get("xiang_time"+roleInfo.getRoleId());
	    if (StringUtils.isEmpty(xiang_time)) {
			//使用摄药香
			//ScreenCapture.mouseClick(device, "1308 675");// # 打开包裹
			ScreenCapture.mouseClick(device, "987 488");// # 
			ScreenCapture.mouseClick(device, "511 404");// # 
			ScreenCapture.mouseClick(device, "1156 52");// 关闭包裹
			redisService.set("xiang_time"+roleInfo.getRoleId(), "xiang_time",1680l);
		}
 	}
}
